/*
 * Copyright 2014 Semidata. All rights reserved.
 */
package com.semidata.rtd.engine.executor;

import com.semidata.rtd.core.service.Service;
import com.semidata.rtd.engine.executor.TaskWorker.Status;

/**
 * @author shewei@semidata.com, She Wei
 *
 */
public class TaskWorkerManager implements Service {
	
	private static final long DEFAULT_CHECK_TIME = 5L;
	private TaskWorker[] workers;
	private Thread thread = null;
	private boolean quit = false;
	private long checkTime;

	
	public TaskWorkerManager(TaskWorker[] workers) {
		this(workers, DEFAULT_CHECK_TIME);
	}
	
	public TaskWorkerManager(TaskWorker[] workers, long checkTime) {
		this.workers = workers;
		this.checkTime = checkTime;
	}

    @Override
    public void start() {
    
    	thread = new Thread(new Runnable() {

			@Override
            public void run() {
				
				while (!quit) {
					
					for (int i = 0; i < workers.length; i++) {
						workers[i].check();
						if (workers[i].getStatus() == TaskWorker.Status.DEAD) {
							TaskWorker worker = workers[i];
							workers[i] = new TaskWorker("TaskWorker" + i);
							worker.kill();
							workers[i].start();
						}
					}
					
					try {
	                    Thread.sleep(checkTime);
                    } catch (InterruptedException e) {
	                }
				}
				
				boolean flag = true;
				
				while (flag) {
					
					flag = false;
					
					for (int i = 0; i < workers.length; i++) {
						workers[i].check();
						Status status = workers[i].getStatus();
						
						if (status == TaskWorker.Status.DEAD && !workers[i].isDead()) {
							workers[i].kill();
						}
						
						if (status == TaskWorker.Status.RUNNING || status == TaskWorker.Status.CANCELLING) {
							flag = true;
							break;
						}
					}
					
					try {
	                    Thread.sleep(checkTime);
                    } catch (InterruptedException e) {
	                }
				}
            }
    		
    	}, "TaskWorkerManager");
    	
    	
    	thread.start(); 
    }

	@Override
    public void stop() {
		quit  = true;

		if (thread != null) {
			try {
	            thread.join();
            } catch (InterruptedException e) {
            }
		}
		
    }
	
	

}
